/**
 * Copyright 2009 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.sapien.action.admin;

import java.util.ArrayList;
import java.util.List;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.validation.SkipValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.code.sapien.interceptor.UserAware;
import com.google.code.sapien.model.Category;
import com.google.code.sapien.model.User;
import com.google.code.sapien.security.RequiresAdministrator;
import com.google.code.sapien.security.RolePermissions;
import com.google.code.sapien.service.CategoryService;
import com.google.inject.Inject;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;

/**
 * Admin Category Action, used to administer categories.
 * @author Adam
 * @version $Id: CategoryAction.java 30 2010-01-10 19:05:55Z a.ruggles $
 * 
 * Created on Feb 9, 2009 at 11:13:23 PM 
 */
@Validations(
		requiredStrings = {
				@RequiredStringValidator(fieldName = "name",
						message = "Required Field.", key = "validation.required"),
				@RequiredStringValidator(fieldName = "description",
						message = "Required Field.", key = "validation.required")
		} 
)
public class CategoryAction extends ActionSupport implements ModelDriven<Category>, UserAware {
	/**
	 * Serial Version UID.
	 */
	private static final long serialVersionUID = -785225937234981491L;

    /**
	 * A list of categories.
	 */
	private List<Category> categories = new ArrayList<Category>();

	/**
	 * Category entity data model.
	 */
	private Category category = new Category();

	/**
	 * The category service.
	 */
	protected final CategoryService categoryService;

	/**
     * The <code>Logger</code> is used by the application to generate a log messages.
     */
    private static final Logger LOG = LoggerFactory.getLogger(CategoryAction.class);

	/**
	 * The logged in user.
	 */
	private User currentUser;

	/**
	 * Constructor.
	 * @param categoryService The category service.
	 */
	@Inject
	public CategoryAction(final CategoryService categoryService) {
		super();
		this.categoryService = categoryService;
	}

	/**
	 * Prepares the category add page.
	 * @return SUCCESS.
	 */
	@Action("new-category")
	@SkipValidation
	@RequiresAdministrator
	public String add() {
		return SUCCESS;
	}

	/**
	 * Creates a category.
	 * @return SUCCESS.
	 */
	@Action(value = "create-category", results = {
			@Result(name = "input", location = "new-category.jsp"),
			@Result(name = "success", location = "category.jsp")
			}
	)
	@RequiresAdministrator
	public String create() {
		categoryService.add(category, currentUser);
		addActionMessage(this.getText("create-category.success", "The category was created successfully."));
		return execute();
	}

	/**
	 * Prepares the category edit page.
	 * @return SUCCESS.
	 */
	@Action("edit-category")
	@RequiresAdministrator
	@SkipValidation
	public String edit() {
		category = categoryService.get(category.getId());
		LOG.debug("category info {}", category);
		return SUCCESS;
	}

	/**
	 * Prepares the categories page.
	 * @return SUCCESS.
	 * @see com.opensymphony.xwork2.ActionSupport#execute()
	 */
	@Override @SkipValidation
	@RequiresAdministrator
	public String execute() {
		categories = categoryService.getAll();
		return SUCCESS;
	}

	/**
	 * Returns categories.
	 * @return the categories.
	 */
	public List<Category> getCategories() {
		return categories;
	}

	/**
	 * {@inheritDoc}
	 * @see com.opensymphony.xwork2.ModelDriven#getModel()
	 */
	public Category getModel() {
		return category;
	}

	/**
	 * Returns a JSON array containing all the categories. 
	 * @return SUCCESS.
	 */
	@Action("json-categories")
	@SkipValidation
	@RequiresAdministrator
	public String json() {
		categories = categoryService.getAll();
		return SUCCESS;
	}

	/**
	 * Removes a category.
	 * @return SUCCESS.
	 */
	@Action(value = "remove-category", results = {
			@Result(name = "success", location = "category.jsp")
			}
	)
	@SkipValidation
	@RequiresAdministrator
	public String remove() {
		categoryService.remove(category, currentUser);
		addActionMessage(this.getText("remove-category.success", "The category was removed successfully."));
		return execute();
	}

	/**
	 * {@inheritDoc}
	 * @see com.google.code.sapien.interceptor.UserAware#setCurrentUser(User)
	 */
	public void setCurrentUser(final User currentUser) {
		this.currentUser = currentUser;
	}

	/**
	 * Updates a category.
	 * @return SUCCESS;
	 */
	@Action(value = "update-category", results = {
			@Result(name = "input", location = "edit-category.jsp"),
			@Result(name = "success", location = "category.jsp")
			}
	)
	@RequiresAdministrator
	public String update() {
		categoryService.update(category, currentUser);
		addActionMessage(this.getText("update-category.success", "Your updates were saved successfully."));
		return execute();
	}
}
